package com.company.anr.copy;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.AccessDeniedException;
import java.nio.file.FileSystemException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Stream;

/**
 * MergeMonkeyLog（无备份版）
 *
 * - 仅遍历 A 当日目录第一层下以 "_analysis.txt" 结尾的普通文件（大小写精确）。
 * - 若 B 目录存在同名文件：向 A 文件末尾追加分隔行与标题，再把 B 文件全文流式追加到 A（UTF-8）。
 * - 若 B 不存在：打印 WARN，不写入。
 * - 读写全程 UTF-8，仅使用 WRITE + APPEND 打开 A，不创建新文件。
 * - 打印处理日志与最终汇总。
 * - 追加成功后，将被修改的 A 文件名从 *_analysis.txt 重命名为 *_NEWanalysis.txt（若冲突自动加序号）。
 */
public class MergeMonkeyLog {

    // 根目录（注意反斜杠转义）
    private static final Path ROOT_A = Paths.get("D:\\ANR-WORK-DETAIL");
    private static final Path ROOT_B = Paths.get("D:\\AMONKEY\\ANR-WORK-DETAIL");

    public static void main(String[] args) {
        String today = todayFolderName();
        Path dayA = ROOT_A.resolve(today);
        Path dayB = ROOT_B.resolve(today);

        // dayA 必须存在且为目录
        if (!Files.isDirectory(dayA)) {
            System.err.println("[ERROR] dayA not found or not a directory: " + dayA);
            System.exit(2);
            return;
        }

        // dayB 不存在：仅警告，后续等价于所有同名文件缺失
        if (!Files.isDirectory(dayB)) {
            System.out.println("[WARN] dayB not found or not a directory: " + dayB + " (peer files will be treated as missing)");
        }

        processDay(dayA, dayB);
        System.exit(0);
    }

    // 返回当日子目录名：MM-dd（使用 LocalDate + DateTimeFormatter）
    static String todayFolderName() {
        LocalDate now = LocalDate.now();
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("MM-dd");
        return now.format(fmt);
    }

    // 处理当日目录
    static void processDay(Path dayA, Path dayB) {
        int nSuccess = 0;
        int nMissing = 0;
        int nErrors = 0;

        List<Path> candidates = new ArrayList<>();
        // 仅第一层，不递归；筛选并按文件名升序
        try (Stream<Path> s = Files.list(dayA)) {
            s.filter(MergeMonkeyLog::isAnalysisFile)
                    .sorted(Comparator.comparing(p -> p.getFileName().toString()))
                    .forEach(candidates::add);
        } catch (IOException e) {
            System.err.println("[ERROR] Failed to list dayA: " + dayA + " - " + e.getClass().getSimpleName() + ": "
                    + e.getMessage());
        }

        if (candidates.isEmpty()) {
            System.out.println("[INFO] No _analysis.txt files in: " + dayA);
        }

        for (Path fileA : candidates) {
            System.out.println("[INFO] Processing: " + fileA);
            String fileName = fileA.getFileName().toString();
            Path fileB = dayB.resolve(fileName);

            if (Files.isRegularFile(fileB)) {
                try {
                    appendHeaderAndFile(fileA, fileB);
                    // 仅在成功追加后，重命名被修改的 A 文件
                    Path newPath = renameModifiedAnalysisFile(fileA);
                    System.out.println("[INFO] Appended and Renamed: " + fileA + " <= " + fileB + " -> " + newPath.getFileName());
                    nSuccess++;
                } catch (AccessDeniedException ade) {
                    System.err.println("[ERROR] " + fileA + " - " + ade.getClass().getSimpleName() + ": " +
                            ade.getMessage() + " — 可能文件被占用或无权限");
                    nErrors++;
                } catch (FileSystemException fse) {
                    System.err.println("[ERROR] " + fileA + " - " + fse.getClass().getSimpleName() + ": " +
                            fse.getMessage() + " — 可能文件被占用或无权限");
                    nErrors++;
                } catch (IOException ioe) {
                    System.err.println("[ERROR] " + fileA + " - " + ioe.getClass().getSimpleName() + ": " +
                            ioe.getMessage());
                    nErrors++;
                }
            } else {
                System.out.println("[WARN] Missing peer: " + fileB);
                nMissing++;
            }
        }

        System.out.println("===== Summary =====");
        System.out.println("Success: " + nSuccess);
        System.out.println("Missing: " + nMissing);
        System.out.println("Errors : " + nErrors);
        System.out.println("===================");
    }

    // 仅第一层普通文件，且文件名以 "_analysis.txt" 结尾（大小写精确）
    static boolean isAnalysisFile(Path p) {
        try {
            return Files.isRegularFile(p) && p.getFileName().toString().endsWith("_analysis.txt");
        } catch (Exception e) {
            return false;
        }
    }

    // 向 A 末尾追加分隔和 B 的全文内容（UTF-8）
    // 打开 A 仅使用 WRITE + APPEND，不得使用 CREATE/CREATE_NEW
    static void appendHeaderAndFile(Path fileA, Path fileB) throws IOException {
        final String ls = System.lineSeparator();

        try (BufferedWriter bw = Files.newBufferedWriter(
                fileA,
                StandardCharsets.UTF_8,
                StandardOpenOption.WRITE,
                StandardOpenOption.APPEND);
             BufferedReader br = Files.newBufferedReader(fileB, StandardCharsets.UTF_8)) {

            // 固定头部：换行、标题、换行、冒号、换行
            bw.write(ls);
            bw.write("monkey测试后新的日志:");
            bw.write(ls);

            // 流式复制 B -> A
            char[] buf = new char[8192];
            int n;
            while ((n = br.read(buf)) != -1) {
                bw.write(buf, 0, n);
            }
        }
    }

    // 仅对本次“已被追加”的 *_analysis.txt 执行：重命名为 *_NEWanalysis.txt
    // 若目标已存在，则自动追加 (1), (2) ... 避免覆盖
    static Path renameModifiedAnalysisFile(Path fileA) throws IOException {
        String name = fileA.getFileName().toString();
        final String suffix = "_analysis.txt";
        if (!name.endsWith(suffix)) { // 理论上不应发生
            return fileA;
        }
        String base = name.substring(0, name.length() - suffix.length());
        Path parent = fileA.getParent();

        String targetName = base + "_NEWanalysis.txt";
        Path target = parent.resolve(targetName);

        int i = 1;
        while (Files.exists(target)) {
            targetName = base + "_NEWanalysis(" + i + ").txt";
            target = parent.resolve(targetName);
            i++;
        }
        // 此处不使用 REPLACE_EXISTING，避免误覆盖
        return Files.move(fileA, target);
    }
}
